package com.bazhua.bazo.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bazhua.bazo.common.utils.CodeUtil;
import com.bazhua.bazo.repository.entity.*;
import com.bazhua.bazo.repository.mapper.CheckUserMapper;
import com.bazhua.bazo.repository.mapper.CouponMapper;
import com.bazhua.bazo.repository.model.*;
import com.bazhua.bazo.repository.model.result.CommonResult;
import com.bazhua.bazo.repository.model.result.PageListResult;
import com.bazhua.bazo.repository.model.result.ResultUtils;
import com.bazhua.bazo.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: starmile
 * @Description:
 * @Create: 2021-01-25 0:14
 **/
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements ICouponService {

    @Autowired
    private ICouponRecordService couponRecordService;
    @Autowired
    private IShopInfoService shopInfoService;
    @Autowired
    private IWechatUserService wechatUserService;
    @Autowired
    private ICouponCheckRecordService couponCheckRecordService;
    @Autowired
    private ICheckUserService checkUserService;
    @Autowired
    private IAreaService areaService;

    public CommonResult setCoupon(SetCoupon setCoupon, Long shopUserId) {
        QueryWrapper<ShopInfo> shopInfoQueryWrapper = new QueryWrapper<>();
        shopInfoQueryWrapper.eq("shop_admin", shopUserId);
        shopInfoQueryWrapper.eq("shop_status", 2);
        ShopInfo shop = shopInfoService.getOne(shopInfoQueryWrapper);
        if (shop == null || shop.getId() <= 0)
            return ResultUtils.error(90010, "店铺查询为空");
        Coupon coupon = new Coupon();
        coupon.setShopId(shop.getId());
        coupon.setCouponName(setCoupon.getCouponName());
        coupon.setCouponNumber(CodeUtil.createCode());
        coupon.setDetailExplain(setCoupon.getExplain());
        coupon.setCreateTime(new Date());
        coupon.setEffectiveTimeEnd(setCoupon.getEffectiveTimeEnd());
        coupon.setEffectiveTimeStart(setCoupon.getEffectiveTimeStart());
        coupon.setLogoUrl(setCoupon.getLogoUrl());
        coupon.setQuantity(setCoupon.getQuantity());
        coupon.setRemark(setCoupon.getRemark());
        coupon.setStatus(0);
        coupon.setRepetition(setCoupon.getRepetition());
        baseMapper.insert(coupon);

        return ResultUtils.ok();
    }

    private ShopInfo getShopByUserId(Long shopUserId) {
        QueryWrapper<ShopInfo> shopInfoQueryWrapper = new QueryWrapper<>();
        shopInfoQueryWrapper.eq("shop_admin", shopUserId);
        shopInfoQueryWrapper.eq("shop_status", 2);
        ShopInfo shop = shopInfoService.getOne(shopInfoQueryWrapper);
        return shop;
    }

    private ShopInfo getShop(Long shopId) {
        QueryWrapper<ShopInfo> shopInfoQueryWrapper = new QueryWrapper<>();
        shopInfoQueryWrapper.eq("id", shopId);
        ShopInfo shop = shopInfoService.getOne(shopInfoQueryWrapper);
        return shop;
    }

    private WechatUser getUser(Long userId) {
        QueryWrapper<WechatUser> wechatUserQueryWrapper = new QueryWrapper<>();
        wechatUserQueryWrapper.eq("id", userId);
        WechatUser wechatUser = wechatUserService.getOne(wechatUserQueryWrapper);
        return wechatUser;
    }

    public CommonResult getCoupon(Integer couponId, Long userId) {
        Coupon coupon = baseMapper.selectById(couponId);
        if (coupon == null || coupon.getId() <= 0)
            return ResultUtils.error(0, "查询数据为空");
        ShopInfo shop = shopInfoService.getById(coupon.getShopId());
        Integer recordCount = couponRecordService.getCouponRecordCount(coupon.getId(), null, null);
        Integer count = couponRecordService.getCouponRecordCount(coupon.getId(), 0, userId);
        Integer status = count > 0 ? 0: 2;
        CouponDetail detail = new CouponDetail();
        detail.setCouponName(coupon.getCouponName());
        detail.setCouponNumber(coupon.getCouponNumber());
        detail.setCouponStatusDetail(recordCount >= coupon.getQuantity()? "已领完": "未领完");
        detail.setCreateTime(coupon.getCreateTime());
        detail.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
        detail.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
        detail.setId(coupon.getId());
        detail.setLogoUrl(coupon.getLogoUrl());
        detail.setShopRemark(shop.getShopRemark());
        detail.setShopAddress(shop.getShopAddress());
        detail.setExplain(coupon.getDetailExplain());
        detail.setShopLogo(shop.getShopLogo());
        if (shop.getShopAreaId() != null && shop.getShopAreaId() > 0) {
            Area area = areaService.getById(shop.getShopAreaId());
            detail.setShopAreaId(area.getId());
            detail.setShopArea(area.getAreaName());
        }
        if (shop.getShopStreetId() != null && shop.getShopStreetId() > 0) {
            Area street = areaService.getById(shop.getShopStreetId());
            detail.setShopStreetId(street.getId());
            detail.setShopStreet(street.getAreaName());
        }
        detail.setShopName(shop.getShopName());
        detail.setQuantity(coupon.getQuantity());
        detail.setStatus(status);
        detail.setRemark(coupon.getRemark());
        detail.setLatitude(shop.getLatitude());
        detail.setLongitude(shop.getLongitude());
        detail.setShopAdminLogo(shop.getShopAdminLogo());
        detail.setShopAddressName(shop.getShopAddressName());
        detail.setRepetition(coupon.getRepetition());
        return ResultUtils.ok(detail);
    }

    public CommonResult drawCoupon(DramCoupon dramCoupon, Long userId) {
        Coupon coupon = baseMapper.selectById(dramCoupon.getCouponId());
        Integer recordCount = couponRecordService.getCouponRecordCount(coupon.getId(), null, null);
        if (recordCount >= coupon.getQuantity()) {
            return ResultUtils.error(90001, "剩余券码不足，无法领取");
        }
        if (couponRecordService.getCouponRecordCount(coupon.getId(), 0, userId) > 0) {
            return ResultUtils.error(90001, "已有未使用的优惠券，无法重复领取");
        }
        if (!coupon.getRepetition() && couponRecordService.getCouponRecordCount(coupon.getId(), null, userId) > 0) {
            return ResultUtils.error(90001, "此优惠券无法重复领取");
        }
        CouponRecord couponRecord = new CouponRecord();
        couponRecord.setCouponId(coupon.getId());
        couponRecord.setCouponNumber(coupon.getCouponNumber() + (recordCount + 1));
        couponRecord.setCreateTime(new Date());
        couponRecord.setShopId(coupon.getShopId());
        couponRecord.setStatus(0);
        couponRecord.setUserId(userId);
        couponRecordService.saveCouponRecord(couponRecord);
        return ResultUtils.ok(couponRecord.getId());
    }

    public CommonResult getCouponRecordDetail(Long couponRecordId) {
        CouponRecordDetailModel couponRecordDetailModel = new CouponRecordDetailModel();
        CouponRecord couponRecord = couponRecordService.getCouponRecord(couponRecordId);
        if (couponRecord != null) {
            ShopInfo shopInfo = getShop(couponRecord.getShopId());
            Coupon coupon = baseMapper.selectById(couponRecord.getCouponId());
            Integer recordCount = couponRecordService.getCouponRecordCount(coupon.getId(), null, null);
            couponRecordDetailModel.setCouponRecordId(couponRecord.getId());
            couponRecordDetailModel.setCouponName(coupon.getCouponName());
            couponRecordDetailModel.setShopId(shopInfo.getId());
            if (shopInfo.getShopAreaId() != null && shopInfo.getShopAreaId() > 0) {
                Area area = areaService.getById(shopInfo.getShopAreaId());
                couponRecordDetailModel.setShopAreaId(area.getId());
                couponRecordDetailModel.setShopArea(area.getAreaName());
            }
            if (shopInfo.getShopStreetId() != null && shopInfo.getShopStreetId() > 0) {
                Area street = areaService.getById(shopInfo.getShopStreetId());
                couponRecordDetailModel.setShopStreetId(street.getId());
                couponRecordDetailModel.setShopStreet(street.getAreaName());
            }
            couponRecordDetailModel.setCouponStatusDetail(recordCount >= coupon.getQuantity()? "已领完": "未领完");
            couponRecordDetailModel.setExplain(coupon.getDetailExplain());
            couponRecordDetailModel.setShopLogo(shopInfo.getShopLogo());
            couponRecordDetailModel.setShopName(shopInfo.getShopName());
            couponRecordDetailModel.setStatus(couponRecord.getStatus());
            couponRecordDetailModel.setLogoUrl(coupon.getLogoUrl());
            couponRecordDetailModel.setCouponNumber(couponRecord.getCouponNumber());
            couponRecordDetailModel.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
            couponRecordDetailModel.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
            couponRecordDetailModel.setShopRemark(shopInfo.getShopRemark());
            couponRecordDetailModel.setShopAdminLogo(shopInfo.getShopAdminLogo());
            couponRecordDetailModel.setLongitude(shopInfo.getLongitude());
            couponRecordDetailModel.setLatitude(shopInfo.getLatitude());
            couponRecordDetailModel.setRemark(coupon.getRemark());
            couponRecordDetailModel.setShopAddressName(shopInfo.getShopAddressName());
            couponRecordDetailModel.setRepetition(coupon.getRepetition());
        }
        return ResultUtils.ok(couponRecordDetailModel);
    }

    public PageListResult getMyCouponPage(Integer pageNum, Integer pageSize, Long userId) {
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>();
        List<Long> shopIds = shopInfoService.getShopIds(null, null);
        if (shopIds == null || shopIds.size() == 0) {
            return ResultUtils.pageError(90200, "查询数据为空");
        }
        queryWrapper.in("shop_id", shopIds);
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("status", 0);
        Page<CouponRecord> page = new Page<>(pageNum, pageSize);
        Page<CouponRecord> couponRecordPage = couponRecordService.getCouponRecordPage(page, queryWrapper);
        return getCouponRecordPage(couponRecordPage);
    }

    public PageListResult getCouponRecordPage(CouponRecordSearch couponRecordSearch) {
        QueryWrapper<CouponRecord> queryWrapper = new QueryWrapper<>();
        List<Long> shopIds = shopInfoService.getShopIds(null, null);
        if (shopIds == null || shopIds.size() == 0) {
            return ResultUtils.pageError(90200, "查询数据为空");
        }
        queryWrapper.in("shop_id", shopIds);
        if (!StringUtils.isBlank(couponRecordSearch.getCouponName())) {
            QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
            wrapper.eq("coupon_name", couponRecordSearch.getCouponName());
            List<Coupon> list = baseMapper.selectList(wrapper);
            if (list != null && list.size() > 0) {
                List<Long> couponIds = list.stream().map(x -> x.getId()).collect(Collectors.toList());
                queryWrapper.in("coupon_id", couponIds);
            } else {
                return ResultUtils.pageError(90200, "查询数据为空");
            }
        }
        if (!StringUtils.isBlank(couponRecordSearch.getCouponNumber())) {
            queryWrapper.eq("coupon_number", couponRecordSearch.getCouponNumber());
        }
        Page<CouponRecord> page = new Page<>(couponRecordSearch.getPageNum(), couponRecordSearch.getPageSize());
        Page<CouponRecord> couponRecordPage = couponRecordService.getCouponRecordPage(page, queryWrapper);
        return getCouponRecordPage(couponRecordPage);
    }

    private PageListResult getCouponRecordPage(Page<CouponRecord> couponRecordPage) {
        if (couponRecordPage.getRecords() != null && couponRecordPage.getRecords().size() > 0) {
            Page<MyCouponModel> modelPage = new Page<>();
            modelPage.setCurrent(couponRecordPage.getCurrent());
            modelPage.setSize(couponRecordPage.getSize());
            modelPage.setTotal(couponRecordPage.getTotal());
            modelPage.setPages(couponRecordPage.getPages());
            modelPage.setMaxLimit(couponRecordPage.getMaxLimit());
            List<MyCouponModel> list = new ArrayList<>();
            for (CouponRecord couponRecord : couponRecordPage.getRecords()) {
                MyCouponModel myCouponModel = new MyCouponModel();
                ShopInfo shopInfo = getShop(couponRecord.getShopId());
                Coupon coupon = baseMapper.selectById(couponRecord.getCouponId());
                WechatUser wechatUser = getUser(couponRecord.getUserId());
                if (shopInfo == null || wechatUser == null)
                    continue;
                if (shopInfo.getShopAreaId() != null && shopInfo.getShopAreaId() > 0) {
                    Area area = areaService.getById(shopInfo.getShopAreaId());
                    myCouponModel.setShopAreaId(area.getId());
                    myCouponModel.setShopArea(area.getAreaName());
                }
                if (shopInfo.getShopStreetId() != null && shopInfo.getShopStreetId() > 0) {
                    Area street = areaService.getById(shopInfo.getShopStreetId());
                    myCouponModel.setShopStreetId(street.getId());
                    myCouponModel.setShopStreet(street.getAreaName());
                }
                myCouponModel.setCouponRecordId(couponRecord.getId());
                myCouponModel.setUserName(wechatUser.getUserName());
                myCouponModel.setHeadUrl(wechatUser.getHeadUrl());
                myCouponModel.setCouponName(coupon.getCouponName());
                myCouponModel.setShopId(shopInfo.getId());
                myCouponModel.setShopName(shopInfo.getShopName());
                myCouponModel.setStatus(couponRecord.getStatus());
                myCouponModel.setLogoUrl(coupon.getLogoUrl());
                myCouponModel.setCouponNumber(couponRecord.getCouponNumber());
                list.add(myCouponModel);
            }
            modelPage.setRecords(list);
            return ResultUtils.pageOk(modelPage);
        }
        return ResultUtils.pageError(0, "查询数据为空");
    }

    public CommonResult checkCoupon(CheckCoupon checkCoupon, Long userId) {
        WechatUser wechatUser = getUser(userId);
        if (wechatUser.getUserType() == UserType.ShopAdmin) {
            ShopInfo shopInfo = getShopByUserId(userId);
            CouponRecord couponRecord = couponRecordService.getCouponRecordByNumber(checkCoupon.getCouponNumber());
            if (couponRecord.getShopId() != shopInfo.getId()) {
                return ResultUtils.error(90001, "非本优惠券商户工作人员，无法核销");
            }
        } else if (wechatUser.getUserType() == UserType.Shop_Staff) {
            CheckUser checkUser = checkUserService.getCheckUserByUserId(userId);
            CouponRecord couponRecord = couponRecordService.getCouponRecordByNumber(checkCoupon.getCouponNumber());
            if (couponRecord.getShopId() != checkUser.getShopId()) {
                return ResultUtils.error(90001, "非本优惠券商户工作人员，无法核销");
            }
        } else {
            return ResultUtils.error(90001, "非工作人员，无法核销");
        }
        CouponRecord couponRecord = couponRecordService.checkCouponRecord(checkCoupon.getCouponNumber(), userId);
        ShopInfo shopInfo = getShop(couponRecord.getShopId());
        CouponCheckRecord couponCheckRecord = new CouponCheckRecord();
        couponCheckRecord.setCouponId(couponRecord.getCouponId());
        couponCheckRecord.setCouponRecordId(couponRecord.getId());
        couponCheckRecord.setShopAdminId(shopInfo.getShopAdmin());
        couponCheckRecord.setShopId(shopInfo.getId());
        couponCheckRecord.setUserId(userId);
        couponCheckRecord.setCreateTime(new Date());
        couponCheckRecordService.add(couponCheckRecord);
        return ResultUtils.ok();
    }

    public CommonResult hasCoupon(Long couponId, Long userId) {
        CouponRecord couponRecord = couponRecordService.getCouponRecordByCouponId(couponId, 0, userId);
        return ResultUtils.ok(couponRecord == null ? null : couponRecord.getId());
    }

    public CommonResult auditCoupon(Long couponId) {
        return changeState(couponId, 1);
    }

    public CommonResult forbiddenCoupon(Long couponId) {
        return changeState(couponId, 3);
    }

    private CommonResult changeState(Long couponId, Integer status) {
        Coupon coupon = baseMapper.selectById(couponId);
        if (coupon == null) {
            return ResultUtils.error(400, "优惠券不存在！");
        }
        coupon.setStatus(status);
        Boolean result = baseMapper.updateById(coupon) > 0;
        return ResultUtils.ok(result);
    }

    public PageListResult page(CouponSearch search, Long userId) {
        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
        List<Long> shopIds = shopInfoService.getShopIds(search.getShopAreaId(), search.getShopStreetId());
        if (shopIds == null || shopIds.size() == 0) {
            return ResultUtils.pageError(90200, "查询数据为空");
        }
        wrapper.in("shop_id", shopIds);
        wrapper.orderByDesc("create_time");
        if (search.getStatus() == null) {
            wrapper.eq("status", 1);
        }
        if (userId != null && userId > 0) {
            ShopInfo shopInfo = getShopByUserId(userId);
            if (shopInfo != null) {
                wrapper.eq("shop_id", shopInfo.getId());
            } else {
                return ResultUtils.pageError(90200, "店铺未审核或已禁用");
            }
        }
        Page<Coupon> page = new Page<>(search.getPageNum(), search.getPageSize());
        page = baseMapper.selectPage(page, wrapper);
        return getCouponPage(page);
    }

    private PageListResult getCouponPage(Page<Coupon> page) {
        if (page.getRecords() != null && page.getRecords().size() > 0) {
            Page<CouponModel> modelPage = new Page<CouponModel>();
            modelPage.setCurrent(page.getCurrent());
            modelPage.setSize(page.getSize());
            modelPage.setTotal(page.getTotal());
            modelPage.setPages(page.getPages());
            modelPage.setMaxLimit(page.getMaxLimit());
            List<CouponModel> list = new ArrayList<>();
            for (Coupon coupon : page.getRecords()) {
                Integer drawCount = couponRecordService.getCouponRecordCount(coupon.getId(), 0, null);
                Integer checkedCount = couponRecordService.getCouponRecordCount(coupon.getId(), 1, null);
                ShopInfo shopInfo = getShop(coupon.getShopId());
                CouponModel couponModel = new CouponModel();
                couponModel.setId(coupon.getId());
                couponModel.setCouponName(coupon.getCouponName());
                couponModel.setCouponNumber(coupon.getCouponNumber());
                couponModel.setLogoUrl(coupon.getLogoUrl());
                couponModel.setCreateTime(coupon.getCreateTime());
                couponModel.setQuantity(coupon.getQuantity());
                couponModel.setEffectiveTimeEnd(coupon.getEffectiveTimeEnd());
                couponModel.setEffectiveTimeStart(coupon.getEffectiveTimeStart());
                couponModel.setRemark(coupon.getRemark());
                couponModel.setDrawQuantity(drawCount);
                couponModel.setCheckedQuantity(checkedCount);
                if (shopInfo == null || shopInfo.getId() <= 0)
                    continue;
                if (shopInfo.getShopAreaId() != null && shopInfo.getShopAreaId() > 0) {
                    Area area = areaService.getById(shopInfo.getShopAreaId());
                    couponModel.setShopAreaId(area.getId());
                    couponModel.setShopArea(area.getAreaName());
                }
                if (shopInfo.getShopStreetId() != null && shopInfo.getShopStreetId() > 0) {
                    Area street = areaService.getById(shopInfo.getShopStreetId());
                    couponModel.setShopStreetId(street.getId());
                    couponModel.setShopStreet(street.getAreaName());
                }
                couponModel.setStatus(coupon.getStatus());
                couponModel.setShopName(shopInfo.getShopName());
                couponModel.setLatitude(shopInfo.getLatitude());
                couponModel.setLongitude(shopInfo.getLongitude());
                couponModel.setReceivedQuantity(drawCount + checkedCount);
                couponModel.setSurplusQuantity(coupon.getQuantity() - couponModel.getReceivedQuantity());
                couponModel.setShopId(shopInfo.getId());
                couponModel.setRepetition(coupon.getRepetition());
                couponModel.setDetailExplain(coupon.getDetailExplain());
                list.add(couponModel);
            }
            modelPage.setRecords(list);
            return ResultUtils.pageOk(modelPage);
        }
        return ResultUtils.pageError(0, "查询数据为空");
    }
}
